package com.vcourse.service.admin.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.vcourse.service.admin.entity.Permission;
import com.vcourse.service.admin.entity.RolePermission;
import com.vcourse.service.admin.entity.User;
import com.vcourse.service.admin.helper.MemuHelper;
import com.vcourse.service.admin.mapper.PermissionMapper;
import com.vcourse.service.admin.service.PermissionService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.vcourse.service.admin.service.RolePermissionService;
import com.vcourse.service.admin.service.UserService;
import com.vcourse.service.admin.vo.PermissionVo;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 权限 服务实现类
 * </p>
 *
 * @author Zengsh123
 * @since 2020-06-15
 */
@Service
public class PermissionServiceImpl extends ServiceImpl<PermissionMapper, Permission> implements PermissionService {
    @Resource
    private RolePermissionService rolePermissionService;

    @Override
    public List<PermissionVo> queryAllMenu() {
        // 查询所有菜单
        QueryWrapper<Permission> wrapper = new QueryWrapper<>();
        wrapper.orderByDesc("id");
        List<Permission> permissionList = baseMapper.selectList(wrapper);
        // 整理数据

        return searchFirst(permissionList);
    }

    private List<PermissionVo> searchFirst(List<Permission> permissionList) {
        List<PermissionVo> treeList = new ArrayList<>();
        // 1. 找到最上级菜单
        for (Permission permission : permissionList) {
            if ("0".equals(permission.getPid())) {
                PermissionVo permissionVo = new PermissionVo();
                BeanUtils.copyProperties(permission, permissionVo);
                permissionVo.setLevel(1);
                // 递归搜索所有子菜单
                searchNext(permissionVo, permissionList);
                treeList.add(permissionVo);
            }
        }
        return treeList;
    }

    /**
     * 递归查找子节点
     * @param parent 父菜单
     */
    private void searchNext(PermissionVo parent, List<Permission> permissionList) {
        for (Permission permission : permissionList) {
            if (parent.getId().equals(permission.getPid())) {
                PermissionVo treeNode = new PermissionVo();
                BeanUtils.copyProperties(permission, treeNode);
                treeNode.setLevel(parent.getLevel() + 1);
                // 递归搜索该菜单的所有下级
                searchNext(treeNode, permissionList);
                parent.getChildren().add(treeNode);
            }
        }
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean removeChildById(String id) {
        List<String> idList = new ArrayList<>();
        this.selectChildListById(id, idList);
        //把根据节点id放到list中
        idList.add(id);
        baseMapper.deleteBatchIds(idList);
        return true;
    }

    /**
     * 根据用户id获取用户菜单
     */
    @Override
    public List<String> selectPermissionValueByUserId(String id) {
        List<String> selectPermissionValueList;
        if(this.isSysAdmin(id)) {
            //如果是系统管理员，获取所有权限
            selectPermissionValueList = baseMapper.selectAllPermissionValue();
        } else {
            selectPermissionValueList = baseMapper.selectPermissionValueByUserId(id);
        }
        return selectPermissionValueList;
    }

    /**
     * 递归获取子节点
     * @param id 父id
     * @param idList id集合
     */
    private void selectChildListById(String id, List<String> idList) {
        QueryWrapper<Permission> wrapper = new QueryWrapper<>();
        wrapper.select("id").eq("pid", id);
        List<Object> list = baseMapper.selectObjs(wrapper);
        for (Object s : list) {
            selectChildListById((String) s, idList);
            idList.add((String) s);
        }
    }

    /**
     * 给角色分配权限
     */
    @Override
    public void saveRolePermissionRelationShip(String roleId, String[] permissionIds) {

        rolePermissionService.remove(new QueryWrapper<RolePermission>().eq("role_id", roleId));

        List<RolePermission> rolePermissionList = new ArrayList<>();
        for(String permissionId : permissionIds) {
            if(StringUtils.isEmpty(permissionId)) {
                continue;
            }

            RolePermission rolePermission = new RolePermission();
            rolePermission.setRoleId(roleId);
            rolePermission.setPermissionId(permissionId);
            rolePermissionList.add(rolePermission);
        }
        rolePermissionService.saveBatch(rolePermissionList);
    }

    @Override
    public List<PermissionVo> selectAllMenu(String roleId) {

        List<Permission> allPermissionList = baseMapper.selectList(new QueryWrapper<Permission>().orderByAsc("CAST(id AS SIGNED)"));

        //根据角色id获取角色权限
        List<RolePermission> rolePermissionList = rolePermissionService.list(new QueryWrapper<RolePermission>().eq("role_id",roleId));
        for (int i = 0; i < allPermissionList.size(); i++) {
            Permission permission = allPermissionList.get(i);
            for (int m = 0; m < rolePermissionList.size(); m++) {
                RolePermission rolePermission = rolePermissionList.get(m);
                if(rolePermission.getPermissionId().equals(permission.getId())) {
                    permission.setSelect(true);
                }
            }
        }

        return searchFirst(allPermissionList);
    }

    @Override
    public List<JSONObject> selectPermissionByUserId(String userId) {
        List<Permission> selectPermissionList = null;
        if(this.isSysAdmin(userId)) {
            //如果是超级管理员，获取所有菜单
            selectPermissionList = baseMapper.selectList(null);
        } else {
            selectPermissionList = baseMapper.selectPermissionByUserId(userId);
        }
        List<PermissionVo> treeList = searchFirst(selectPermissionList);
        return MemuHelper.bulid(treeList);
    }

    @Resource
    private UserService userService;

    /**
     * 判断用户是否系统管理员
     */
    private boolean isSysAdmin(String userId) {
        User user = userService.getById(userId);

        if(null != user && "admin".equals(user.getUsername())) {
            return true;
        }
        return false;
    }
}
